﻿using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace OMR.Lib.Database.Tests
{
    [TestClass]
    public class DBTests
    {
        Storage st;

        [TestInitialize]
        public void InitStorage()
        {
            string dbPath = @"D:\Proje\Dropbox\proje\library\OMR.Database\DB_1\";

            st = new Storage(dbPath);
            st.RegisterTypes(
                                typeof(TestEntity),
                                typeof(AnotherEntity)
                            );
        }

        [TestMethod()]
        public void AddEntity()
        {
            DB db = new DB(st);
            db.Initialize();

            int _yearsOld = 25;

            var actual = new TestEntity() { YearsOld = _yearsOld };
            db.Add(actual);

            var expected = db.Query<TestEntity>(f => f.YearsOld == actual.YearsOld);

            Assert.IsNotNull(expected);
        }

        [TestMethod()]
        public void QueryEntityRandom()
        {
            DB db = new DB(st);
            db.Initialize();

            for (int i = 0; i < 30; i++)
            {
                db.Add(new TestEntity() { YearsOld = i % 70 });
            }

            var expected = db.Query<TestEntity>(f => f.YearsOld == 20).Count();

            Assert.IsTrue(expected > 0);
        }

        [TestMethod]
        public void EntityIsExists()
        {
            DB db = new DB(st);
            db.Initialize();

            var actual = new TestEntity();
            db.Add(actual);

            Assert.IsTrue(db.Exists(actual));
        }

        [TestMethod]
        public void RemoveEntity()
        {
            DB db = new DB(st);
            db.Initialize();

            var actual = new TestEntity();

            db.Add(actual);

            Assert.IsTrue(db.Remove(actual));
        }

        [TestMethod]
        public void UpdateEntity()
        {
            DB db = new DB(st);
            db.Initialize();

            var actual = new TestEntity();
            db.Add(actual);

            var newYearsOld = actual.YearsOld = -5;

            actual.YearsOld = newYearsOld;

            Assert.IsTrue(db.Update(actual));

            Assert.AreEqual(actual.YearsOld, newYearsOld);
        }

        [TestMethod]
        public void AddOrUpdateEntity()
        {
            DB db = new DB(st);
            db.Initialize();

            var actual_1 = new TestEntity(); // will be updated
            var actual_2 = new TestEntity(); // will 

            db.Add(actual_1);

            db.AddOrUpdate(actual_1);
            db.AddOrUpdate(actual_2);
        }

        [TestMethod]
        public void ReloadTest()
        {
            DB db_1 = new DB(st);
            db_1.Initialize();

            for (int i = 0; i < 10; i++)
            {
                db_1.Add(new TestEntity());
            }

            DB db_2 = new DB(st);
            db_2.Initialize();

            Assert.AreEqual(10, db_2.Count<TestEntity>());
        }

        [TestMethod]
        public void MultiTypeTest()
        {
            DB db_1 = new DB(st);
            db_1.Initialize();

            for (int i = 0; i < 10; i++)
            {
                db_1.Add(new TestEntity());
            }

            for (int i = 0; i < 10; i++)
            {
                db_1.Add(new AnotherEntity() { StringProperty = i + ". prop" });
            }

            DB db_2 = new DB(st);
            db_2.Initialize();

            Assert.AreEqual(10, db_2.Count<TestEntity>());
        }

        [TestCleanup]
        public void CleanUp()
        {
            foreach (var f in System.IO.Directory.GetFiles(StorageTests.dbPath))
            {
                System.IO.File.Delete(f);
            }
        }
    }
}
